import { render, useState, Fragment } from "@wordpress/element";
import styled, { createGlobalStyle } from "styled-components";
import { __ } from "@wordpress/i18n";

const BeaconOffset = createGlobalStyle`
	@media only screen and (min-width: 1024px) {
		.BeaconFabButtonFrame.BeaconFabButtonFrame {
			right: 340px;
		}
	}
`;

/**
 * Render a component in a newly created div.
 *
 * @param {React.Component} Component The component to render.
 *
 * @returns {void}
 */
function renderComponent( Component ) {
	const element = document.createElement( "div" );
	element.setAttribute( "id", "yoast-helpscout-beacon" );

	render( <Component />, element );

	document.body.appendChild( element );
}

/**
 * Checks whether the current page contains upsells.
 *
 * @returns {boolean} Whether the current page contains upsells.
 */
function pageHasUpsells() {
	return !! document.getElementById( "sidebar" );
}

/**
 * Loads the HelpScout Beacon script.
 *
 * @param {string} beaconId    The ID to pass to the HelpScout Beacon.
 * @param {string} sessionData Optional. JSON encoded session data to pass to the HelpScout Beacon.
 *
 * @returns {void}
 */
function loadHelpScout( beaconId, sessionData = "" ) {
	// This IIFE is directly from HelpScout to insert their beacon.
	( function( window, document ) {
		let beacon = window.Beacon || function() {};

		/**
		 * Inserts the HelpScout beacon script.
		 *
		 * @returns {void}
		 */
		function insertScript() {
			const domScriptElement = document.getElementsByTagName( "script" )[ 0 ];
			const scriptElement = document.createElement( "script" );

			scriptElement.type = "text/javascript";
			scriptElement.async = true;
			scriptElement.src = "https://beacon-v2.helpscout.net";
			domScriptElement.parentNode.insertBefore( scriptElement, domScriptElement );
		}

		if ( window.Beacon = beacon = function( method, options, data ) {
			window.Beacon.readyQueue.push( { method: method, options: options, data: data } );
		}, beacon.readyQueue = [], "complete" === document.readyState ) {
			return insertScript();
		}

		if ( window.attachEvent ) {
			window.attachEvent( "onload", insertScript );
		} else {
			window.addEventListener( "load", insertScript, false );
		}
	}( window, document, window.Beacon || function() {} ) );

	// eslint-disable-next-line new-cap
	window.Beacon( "init", beaconId );
	if ( sessionData !== "" ) {
		// eslint-disable-next-line new-cap
		window.Beacon( "session-data", JSON.parse( sessionData ) );
	}

	if ( pageHasUpsells() ) {
		renderComponent( BeaconOffset );
	}
}

/**
 * Loads a button that, when clicked, asks the user's consent before possibly loading in the HelpScout beacon.
 *
 * @param {string} beaconId    The ID to pass to the HelpScout Beacon.
 * @param {string} sessionData Optional. JSON encoded session data to pass to the HelpScout Beacon.
 *
 * @returns {void}
 */
function loadHelpScoutConsent( beaconId, sessionData = null ) {
	const Frame = styled.div`
		border-radius: 60px;
		height: 60px;
		position: fixed;
		transform: scale(1);
		width: 60px;
		z-index: 1049;
		bottom: 40px;
		box-shadow: rgba(0, 0, 0, 0.1) 0 4px 7px;
		right: 40px;
		top: auto;
		border-width: initial;
		border-style: none;
		border-color: initial;
		border-image: initial;
		transition: box-shadow 250ms ease 0s, opacity 0.4s ease 0s, scale 1000ms ease-in-out 0s, transform 0.2s ease-in-out 0s;
	`;

	const SvgContainer = styled.span`
		-webkit-box-align: center;
		align-items: center;
		color: white;
		cursor: pointer;
		display: flex;
		height: 100%;
		-webkit-box-pack: center;
		justify-content: center;
		left: 0;
		pointer-events: none;
		position: absolute;
		text-indent: -99999px;
		top: 0;
		width: 60px;
		will-change: opacity, transform;
		opacity: 1 !important;
		transform: rotate(0deg) scale(1) !important;
		transition: opacity 80ms linear 0s, transform 160ms linear 0s;
	`;

	/**
	 * Initializes the SpeechBubble component.
	 *
	 * @constructor
	 *
	 * @returns {React.Element} A SpeechBubble element.
	 */
	const SpeechBubble = () => {
		return (
			<SvgContainer>
				<svg xmlns="http://www.w3.org/2000/svg" width="52" height="52">
					{ /* eslint-disable-next-line max-len */ }
					<path d="M27.031 32h-2.488v-2.046c0-.635.077-1.21.232-1.72.154-.513.366-.972.639-1.381.272-.41.58-.779.923-1.109.345-.328.694-.652 1.049-.97l.995-.854a6.432 6.432 0 0 0 1.475-1.568c.39-.59.585-1.329.585-2.216 0-.635-.117-1.203-.355-1.703a3.7 3.7 0 0 0-.96-1.263 4.305 4.305 0 0 0-1.401-.783A5.324 5.324 0 0 0 26 16.114c-1.28 0-2.316.375-3.11 1.124-.795.75-1.286 1.705-1.475 2.865L19 19.693c.356-1.772 1.166-3.165 2.434-4.176C22.701 14.507 24.26 14 26.107 14c.947 0 1.842.131 2.682.392.84.262 1.57.648 2.185 1.16a5.652 5.652 0 0 1 1.475 1.892c.368.75.551 1.602.551 2.556 0 .728-.083 1.364-.248 1.909a5.315 5.315 0 0 1-.693 1.467 6.276 6.276 0 0 1-1.048 1.176c-.403.351-.83.71-1.28 1.073-.498.387-.918.738-1.26 1.057a4.698 4.698 0 0 0-.836 1.006 3.847 3.847 0 0 0-.462 1.176c-.095.432-.142.955-.142 1.568V32zM26 37a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3z" fill="#FFF" />
				</svg>
			</SvgContainer>
		);
	};

	const Button = styled.button`
		-webkit-appearance: none;
		-webkit-box-align: center;
		align-items: center;
		bottom: 0;
		display: block;
		height: 60px;
		-webkit-box-pack: center;
		justify-content: center;
		line-height: 60px;
		position: relative;
		user-select: none;
		z-index: 899;
		background-color: rgb(164, 40, 106);
		color: white;
		cursor: pointer;
		min-width: 60px;
		-webkit-tap-highlight-color: transparent;
		border-radius: 200px;
		margin: 0;
		outline: none;
		padding: 0;
		border-width: initial;
		border-style: none;
		border-color: initial;
		border-image: initial;
		transition: background-color 200ms linear 0s, transform 200ms linear 0s;
	`;

	/**
	 * Initializes the HelpScoutBeaconAskConsentButton component.
	 *
	 * @constructor
	 *
	 * @returns {React.Element} A HelpScoutBeaconAskConsentButton element.
	 */
	const HelpScoutBeaconAskConsentButton = () => {
		const [ show, setShow ] = useState( true );
		const hasUpsells = pageHasUpsells();

		/**
		 * Loads HelpScout beacon and then disables the ask consent button.
		 *
		 * @returns {void}
		 */
		function onClick() {
			const askConsentText = __(
				"When you click OK we will load our HelpScout beacon, which will load data from HelpScout. " +
				"This beacon can potentially also set cookies.",
				"wordpress-seo"
			);

			// eslint-disable-next-line no-alert
			if ( window.confirm( askConsentText ) ) {
				// eslint-disable-next-line callback-return
				loadHelpScout( beaconId, sessionData );
				// eslint-disable-next-line new-cap
				window.Beacon( "open" );

				// Hide the consent asking button only after the HelpScout button is visible. There is no callback for that though.
				window.setTimeout( () => {
					setShow( false );
				}, 1000 );
			}
		}

		return (
			<Fragment>
				{ hasUpsells && <BeaconOffset /> }
				{ show && <Frame className={ hasUpsells ? "BeaconFabButtonFrame" : "" }>
					<Button onClick={ onClick }>
						<SpeechBubble />
					</Button>
				</Frame> }
			</Fragment>
		);
	};

	renderComponent( HelpScoutBeaconAskConsentButton );
}

window.wpseoHelpScoutBeacon = loadHelpScout;
window.wpseoHelpScoutBeaconConsent = loadHelpScoutConsent;
